<!DOCTYPE html>
<html>
<head>
    <!--Import Google Icon Font-->
    <link type="text/css" rel="stylesheet" href="css/material-icons.css"/>
    <!--Import materialize.css-->
    <link type="text/css" rel="stylesheet" href="css/materialize.min.css" media="screen,projection"/>
    <title>Instance Detail</title>

    <!--Let browser know website is optimized for mobile-->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <style>
        nav.clean {
            background: none;
            box-shadow: none;
        }

        .breadcrumb:before {
            color: rgba(0, 0, 0, 0.7);
        }

        .breadcrumb, .breadcrumb:last-child {
            color: rgba(0, 0, 0, 1);
        }
    </style>
</head>
<body>
<div class="container">
    <div class="section">
        <nav class="clean">
            <div class="nav-wrapper">
                <div class="col s12" id="breadcrumb-path">
                    <a href="/compute_pools.html" class="breadcrumb" id="pool-caption"></a>
                </div>
            </div>
        </nav>
    </div>
    <div class="divider"></div>
    <div class="section">
      <div class="row">
        <div class="col m8 push-m1 s12">
          <div class="row">
            <table class="striped">
              <tbody id="detail">
              </tbody>
            </table>
          </div>
        </div>
      </div>


    </div>

    <div class="section">
        <div class="row">
            <div class="col m2">
                <a class="waves-effect waves-light blue-grey lighten-2 btn" onclick="window.history.back()" id="back-caption"><i
                        class="material-icons left">chevron_left</i></a>
            </div>
        </div>
    </div>
    <!-- modal -->
    <div class="modal" id="modal_core">
      <div class="modal-content">
          <h4>Change Guest Cores</h4>
          <div class="row">
            <div class="col m4 s12">
              Current Cores: <span id="current_core"></span>
            </div>
          </div>
          <div class="row">
            <div class="input-field col m4 s12">
              <label for="new_core">Change to</label>
              <input type="text" id="new_core">
            </div>
          </div>
      </div>
      <div class="modal-footer">
          <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
          <a href="#" class="modal-close waves-effect waves-green btn-flat" onclick="changeCores()">Yes</a>
      </div>
    </div>
    <!-- modify memory -->
    <div class="modal" id="modal_memory">
      <div class="modal-content">
          <h4>Change Guest Memory</h4>
          <div class="row">
            <div class="col m4 s12">
              Current Memory: <span id="current_memory"></span>
            </div>
          </div>
          <div class="row">
            <div class="input-field col m4 s12">
              <label for="new_memory">Change to (MiB)</label>
              <input type="text" id="new_memory">
            </div>
          </div>
      </div>
      <div class="modal-footer">
          <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
          <a href="#" class="modal-close waves-effect waves-green btn-flat" onclick="changeMemory()">Yes</a>
      </div>
    </div>
    <!-- modify password -->
    <div class="modal" id="modal_password">
      <div class="modal-content">
          <h4>Change Password</h4>
          <div class="row">
            <div class="input-field col m4 s12">
              <label for="new_user">Admin Name</label>
              <input type="text" id="new_user">
            </div>
          </div>
          <div class="row">
            <div class="input-field col m4 s12">
              <label for="new_password">Password( generate a new one when blank )</label>
              <input type="text" id="new_password">
            </div>
          </div>
      </div>
      <div class="modal-footer">
          <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
          <a href="#" class="modal-close waves-effect waves-green btn-flat" onclick="changePassword()">Yes</a>
      </div>
    </div>
    <!-- extend disk -->
    <div class="modal" id="modal_disk">
      <div class="modal-content">
          <h4>Extend Disk</h4>
          <div class="row">
            <div class="col m4 s12">
              Current disk size: <span id="current_disk"></span>
            </div>
          </div>
          <div class="row">
            <div class="input-field col m4 s12">
              <label for="new_disk">Extend to (GiB)</label>
              <input type="text" id="new_disk">
            </div>
          </div>
      </div>
      <div class="modal-footer">
          <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
          <a href="#" class="modal-close waves-effect waves-green btn-flat" id='extend_confirm'>Yes</a>
      </div>
    </div>
    <!-- shrink disk -->
    <div class="modal" id="modal_shrink">
      <div class="modal-content">
          <h4>Shrink Disk</h4>
          <p>
            <span type="flow-text">
              Do you want to shrink this volume to save more disk space? It may take a long time.
            </span>
          </p>
      </div>
      <div class="modal-footer">
          <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
          <a href="#" class="modal-close waves-effect waves-green btn-flat" id='shrink_confirm'>Yes</a>
      </div>
    </div>
    <!--general modal-->
    <div class="modal" id="modal-container">
      <div class="modal-content" id="modal-content">
      </div>
      <div class="modal-footer">
          <a href="#" class="modal-close waves-effect waves-green btn-flat"></a>
          <a href="#" class="modal-close waves-effect waves-green btn-flat" id='modal-confirm-button'></a>
      </div>
    </div>
</div>

<!--JavaScript at end of body for optimized loading-->
<script type="text/javascript" src="/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/js/materialize.min.js"></script>
<script type="text/javascript" src="js/nano.js"></script>
<script>
    N.ValidateSession();
    var texts = N.GetTexts();
    $('#pool-caption').text(texts.get(N.TagComputePool));
    $('#back-caption').append(texts.get(N.TagBack));
    $('.modal-footer > a:first-child').text(texts.get(N.TagCancel));
    $('.modal-footer > a:last-child').text(texts.get(N.TagConfirm));
    var poolName;
    var cellName;
    var instanceID;
    var ins;
    var MiB = 1 << 20;
    var GiB = 1 << 30;

    M.AutoInit();

    function parseQueryString(){
      var url = window.location.search;
      var queryParams = new Map();
      var queryString = url.substring( url.indexOf('?') + 1 );
      if (0 === queryString.length){
        return queryParams;
      }
      var values = queryString.split("&");
      values.forEach((value) => {
        var p = value.split('=');
        queryParams.set(p[0], p[1]);
      });
      return queryParams;
    }

    function refresh(){
      loadInstance();
    }

    function outputMessage(message){
      $('#instance_list').append(
        $('<div>').addClass('center').append(
          $('<span>').text(message)
        )
      );
    }


    function loadInstance(){
      var url = "/guests/" + instanceID;

      $.getJSON(
        url,
        function(result){
          if (0 != result['error_code']) {
            outputMessage(result['message']);
            return;
          }
          var container = $('#detail');
          container.empty();

          ins = result['data'];
          var guestName = ins['name'];
          var cores = Number(ins['cores']);
          $('#current_core').text(cores);

          var memory = Number(ins['memory']);
          var memoryDisplayed = (memory / MiB) + ' MiB';
          $('#current_memory').text(memoryDisplayed);
          var autoStart;
          if (ins['auto_start']){
            autoStart = $('<i>').addClass('material-icons green-text darken-2 tooltipped').attr('data-position', 'top').
              attr('data-tooltip', texts.get(N.TagEnable)).text('all_inclusive');
          }
          var isRunning = ins['running'];
          var monitorAddress;
          if (ins.hasOwnProperty('internal') && ins['internal'].hasOwnProperty('display_address') ){
            var protocol;
            if (ins['display_protocol']){
              protocol = ins['display_protocol'];
            }else{
              protocol = "vnc";
            }
            monitorAddress = protocol + "://" + ins['internal']['display_address'];
          }
          var monitorOperator = $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('data-position', 'top').attr('onclick', 'showMonitorPassword()')
            .attr('data-tooltip', texts.get(N.TagView)).append(
              $('<i>').addClass('material-icons').text('remove_red_eye')
          );
          var internalAddress = "unavailable";
          if (ins.hasOwnProperty('internal') && ins['internal'].hasOwnProperty('network_address') ){
            internalAddress = ins['internal']['network_address'];
          }
          var allocatedInternal = "";
          if (ins.hasOwnProperty('internal') && ins['internal'].hasOwnProperty('allocated_address') ){
            allocatedInternal = ins['internal']['allocated_address'];
          }
          var externalAddress = "unavailable";
          if (ins.hasOwnProperty('external') && ins['external'].hasOwnProperty('network_address')){
            externalAddress = ins['external']['network_address'];
          }
          var nameOperator = $('<td>');
          var coreOperator = $('<td>');
          var memoryOperator = $('<td>');
          var passwordOperator = $('<td>').append(
            $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('data-position', 'top').attr('onclick', 'showPassword()')
            .attr('data-tooltip', texts.get(N.TagView)).append(
                $('<i>').addClass('material-icons').text('remove_red_eye')
            )
          );
          var lockICON = $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('data-position', 'top').append(
              $('<i>').addClass('material-icons').text('lock_outline')
          );

          if (isRunning){
            nameOperator.append(lockICON.clone().attr('data-tooltip', texts.get(N.TagDisabledWhenRunning)));
            coreOperator.append(lockICON.clone().attr('data-tooltip', texts.get(N.TagDisabledWhenRunning)));
            memoryOperator.append(lockICON.clone().attr('data-tooltip', texts.get(N.TagDisabledWhenRunning)));
            passwordOperator.append(
              $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('data-position', 'top').attr('onclick', 'showModifyPassword()')
              .attr('data-tooltip', texts.get(N.TagChange)).append(
                  $('<i>').addClass('material-icons').text('build')
              )
            );
          }else{
            nameOperator.append(
              $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('onclick', 'showModifyNameModal("' + guestName + '")')
                .attr('data-position', 'top').attr('data-tooltip', texts.get(N.TagChange)).append(
                  $('<i>').addClass('material-icons').text('build')
              )
            );
            coreOperator.append(
              $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('onclick', 'showModalCore()')
                .attr('data-position', 'top').attr('data-tooltip', texts.get(N.TagChange)).append(
                  $('<i>').addClass('material-icons').text('build')
              )
            );
            memoryOperator.append(
              $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('onclick', 'showModalMemory()')
                .attr('data-position', 'top').attr('data-tooltip', texts.get(N.TagChange)).append(
                  $('<i>').addClass('material-icons').text('build')
              )
            );
            passwordOperator.append(lockICON.clone().attr('data-tooltip', texts.get(N.TagDisabledWhenStopped)));
          }
          container.append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagName))
              )
            ).append(
              $('<td>').attr('id', 'guest-name').text(guestName)
            ).append(
              nameOperator
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text("ID")
              )
            ).append(
              $('<td>').text(instanceID)
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagCore))
              )
            ).append(
              $('<td>').attr('id', 'text_core').text(cores)
            ).append(
              coreOperator
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagMemory))
              )
            ).append(
              $('<td>').attr('id', 'text_memory').text(memoryDisplayed)
            ).append(
              memoryOperator
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagPassword))
              )
            ).append(
              $('<td>').attr('id', 'text_password').text("************")
            ).append(
              passwordOperator
            )
          );
          //monitor
          if (monitorAddress){
            container.append(
              $('<tr>').append(
                $('<td>').append(
                  $('<b>').text(texts.get(N.TagMonitorAddress))
                )
              ).append(
                $('<td>').text(monitorAddress)
              ).append(
                $('<td>')
              )
            ).append(
              $('<tr>').append(
                $('<td>').append(
                  $('<b>').text(texts.get(N.TagMonitorPassword))
                )
              ).append(
                $('<td>').attr('id', 'text_monitor_secret').text("************")
              ).append(
                $('<td>').append(
                  monitorOperator
                )
              )
            );
          }
          var index = 0;
          var diskName;
          ins['disks'].forEach((diskSize) =>{
            if (0 == index){
              diskName = texts.get(N.TagSystemDisk);
            }else{
              diskName = texts.get(N.TagDataDisk) +' ' + index;
            }
            var operators = $('<td>');
            if (isRunning){
              operators.append(lockICON.clone().attr('data-tooltip','Disabled when running'));
            }else{
              operators.append(
                $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('data-position', 'top').attr('onclick', 'showExtendDisk(' + index + ')').
                attr('data-tooltip', texts.get(N.TagExtend)).append(
                    $('<i>').addClass('material-icons').text('zoom_out_map')
                )).append(
                $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('data-position', 'top').attr('onclick', 'showShrinkDisk(' + index + ')').
                attr('data-tooltip', texts.get(N.TagShrink)).append(
                    $('<i>').addClass('material-icons').text('system_update_alt')
                ));
            }
            container.append(
              $('<tr>').append(
                $('<td>').append(
                  $('<b>').text(diskName)
                )
              ).append(
                $('<td>').text( Math.floor( diskSize * 100 / GiB) / 100 + ' GiB').attr('id', 'text_disk_' + index)
              ).append(
                operators
              )
            );

            index++;
          });

          //container
          container.append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagInternalAddress))
              )
            ).append(
              $('<td>').text(internalAddress)
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagAllocated))
              )
            ).append(
              $('<td>').text(allocatedInternal)
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagExternalAddress))
              )
            ).append(
              $('<td>').text(externalAddress)
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagSystem))
              )
            ).append(
              $('<td>').text(ins['system'])
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagAutoStart))
              )
            ).append(
              $('<td>').append(
                autoStart
              )
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagComputePool))
              )
            ).append(
              $('<td>').text(ins['pool'])
            ).append(
              $('<td>')
            )
          ).append(
            $('<tr>').append(
              $('<td>').append(
                $('<b>').text(texts.get(N.TagCell))
              )
            ).append(
              $('<td>').text(ins['cell'])
            ).append(
              $('<td>')
            )
          );
          if (ins.hasOwnProperty('create_time')){
            container.append(
              $('<tr>').append(
                $('<td>').append(
                  $('<b>').text(texts.get(N.TagCreate))
                )
              ).append(
                $('<td>').text(ins['create_time'])
              ).append(
                $('<td>')
              )
            );
          }
          if (ins.hasOwnProperty('qos')){
            var qos = ins['qos'];
            var priorityLabel, iopsLabel, bandwidthLabel, textUnlimit, priorityNames;
            if(N.IsChinese()){
              priorityLabel = 'CPU优先级';
              iopsLabel = "磁盘读写限制(每秒)";
              bandwidthLabel = "下/上行带宽";
              textUnlimit = '无限制';
              priorityNames = {
                "high": "高优先",
                "medium": "中优先",
                "low": "低优先",
              };
            }else{
              priorityLabel = 'CPU Priority';
              iopsLabel = "Disk Read&Write(per second)";
              bandwidthLabel = "Inbound/Outbound Bandwidth";
              textUnlimit = "Unlimited";
              priorityNames = {
                "high": "High",
                "medium": "Medium",
                "low": "Low",
              };
            }
            //priority
            if(qos.hasOwnProperty('cpu_priority')){
              var priority = qos['cpu_priority'];
              container.append(
                $('<tr>').append(
                  $('<td>').append(
                    $('<b>').text(priorityLabel)
                  )
                ).append(
                  $('<td>').text(priorityNames[priority])
                ).append(
                  $('<td>').append(
                    $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('onclick', 'showModifyPriority("' + priority + '")')
                      .attr('data-position', 'top').attr('data-tooltip', texts.get(N.TagChange)).append(
                        $('<i>').addClass('material-icons').text('build')
                    )
                  )
                )
              );
            }
            //IOPS
            {
              var read = 0, write = 0;
              if(qos.hasOwnProperty('write_iops')){
                write = Number(qos['write_iops']);
              }
              if(qos.hasOwnProperty('read_iops')){
                read = Number(qos['read_iops']);
              }
              var iops = Math.max(read, write);
              var displayValue;
              if(0 == iops){
                displayValue = textUnlimit;
              }else{
                displayValue = iops + '';
              }
              var operators = $('<td>');
              if (isRunning){
                operators.append(lockICON.clone().attr('data-tooltip','Disabled when running'));
              }else{
                operators.append(
                  $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('onclick', 'showModifyIOPS(' + iops + ')')
                    .attr('data-position', 'top').attr('data-tooltip', texts.get(N.TagChange)).append(
                      $('<i>').addClass('material-icons').text('build')
                  )
                );
              }
              container.append(
                $('<tr>').append(
                  $('<td>').append(
                    $('<b>').text(iopsLabel)
                  )
                ).append(
                  $('<td>').text(displayValue)
                ).append(
                  operators
                )
              );
            }
            //inbound&outbound
            {
              var inbound = 0, outbound = 0;
              if(qos.hasOwnProperty('receive_speed')){
                inbound = Number(qos['receive_speed']);
              }
              if(qos.hasOwnProperty('send_speed')){
                outbound = Number(qos['send_speed']);
              }
              var displayValue;
              if(0 == inbound){
                displayValue = textUnlimit;
              }else if(inbound < (1 << (20 - 3))) {
                displayValue = (inbound >> (10 - 3) ) + ' Kbps';
              }else{
                displayValue = (inbound >> (20 - 3) ) + ' Mbps';
              }

              if(0 == outbound){
                displayValue += ' / ' + textUnlimit;
              }else if(outbound < (1 << (20 - 3))){
                displayValue += ' / ' +  (outbound >> (10 - 3) ) + ' Kbps';
              }else{
                displayValue += ' / ' +  (outbound >> (20 - 3) ) + ' Mbps';
              }

              container.append(
                $('<tr>').append(
                  $('<td>').append(
                    $('<b>').text(bandwidthLabel)
                  )
                ).append(
                  $('<td>').text(displayValue)
                ).append(
                  $('<td>').append(
                    $('<a>').addClass('blue-grey-text tooltipped').attr('href', '#').attr('onclick', 'showModifyBandWidth(' + inbound + ', ' + outbound + ')')
                      .attr('data-position', 'top').attr('data-tooltip', texts.get(N.TagChange)).append(
                        $('<i>').addClass('material-icons').text('build')
                    )
                  )
                )
              );
            }

          }
          M.Tooltip.init($('.tooltipped'));
        }
      );
    }

    function showModifyNameModal(guestName){
      var title, current, label;
      if (N.IsChinese()){
        title = '修改实例名';
        current = '当前名称：' + guestName;
        label = '请输入新名称';
      }else{
        title = 'Modify Name';
        current = 'Current name:' + guestName;
        label = 'New name';
      }
      $('#modal-content').empty().append(
        $('<h4>').text(title)
      ).append(
        $('<div>').addClass('row').text(current)
      ).append(
        $('<div>').addClass('row').append(
          $('<div>').addClass('input-field col m4 s12').append(
            $('<label>').attr('for', 'new-guest-name').text(label)
          ).append(
            $('<input>').attr('type', 'text').attr('id', 'new-guest-name')
          )
        )
      )
      $('#modal-confirm-button').attr('onclick', 'modifyName("' + guestName + '")');
      M.Modal.getInstance($('#modal-container')).open();
    }

    function modifyName(guestName){
      var newName = $('#new-guest-name').val();
      if (!newName){
        if(N.IsChinese()){
          M.toast({html: '请输入新名称'});
        }else{
          M.toast({html: 'Please input new name'});
        }
        return;
      }
      if (newName == guestName){
        if(N.IsChinese()){
          M.toast({html: '名称相同'});
        }else{
          M.toast({html: 'No need to change'});
        }
        return;
      }
      var request = new Object();
      request.name = newName;
      $.ajax({
        url: '/guests/' + instanceID + '/name/',
        method: "PUT",
        dataType: "json",
        data: JSON.stringify(request),
        success: function (result) {
            if (0 != result['error_code']) {
                M.toast({html: 'modify name fail: ' + result['message'], outDuration: 600});
                return;
            }
            if(N.IsChinese()){
              M.toast({html: '实例名已修改'});
            }else{
              M.toast({html: 'Guest name modified'});
            }
            $('#guest-name').text(newName);
            N.WriteOperateLog('modify name of ' + guestName + ' to ' + newName);
        },
        error: function (jqXHR, status, error) {
          M.toast({html: 'request modify guest name fail: ' + error, outDuration: 600});
        }
      });
    }

    function showModalCore(){
      var instance = M.Modal.getInstance($('#modal_core'));
      instance.open();
    }

    function changeCores(){
      var newCores = Number($('#new_core').val());
      $('#new_core').val('');
      if (!Number.isInteger(newCores)){
        M.toast({html: 'invalid core number'});
        return
      }
      var request = new Object();
      request.cores = newCores;
      $.ajax({
        url: '/guests/' + instanceID + '/cores',
        method: "PUT",
        dataType: "json",
        data: JSON.stringify(request),
        success: function (result) {
            if (0 != result['error_code']) {
                M.toast({html: 'modify core fail: ' + result['message'], outDuration: 600});
                return;
            }
            M.toast({html: 'cores of guest modified'});
            $('#text_core').text(newCores);
            $('#current_core').text(newCores);
            N.WriteOperateLog('change core of ' + instanceID + ' to ' + newCores);
        },
        error: function (jqXHR, status, error) {
          M.toast({html: 'request modify guest core fail: ' + error, outDuration: 600});
        }
      });
    }

    function showModalMemory(){
      var instance = M.Modal.getInstance($('#modal_memory'));
      instance.open();
    }

    function changeMemory(){
      var newMemory = Number($('#new_memory').val());
      $('#new_memory').val('');
      if (!Number.isInteger(newMemory)){
        M.toast({html: 'invalid memory size'});
        return
      }
      var memoryInBytes = newMemory * MiB;
      var request = new Object();
      request.memory = memoryInBytes;
      $.ajax({
        url: '/guests/' + instanceID + '/memory',
        method: "PUT",
        dataType: "json",
        data: JSON.stringify(request),
        success: function (result) {
            if (0 != result['error_code']) {
                M.toast({html: 'modify memory fail: ' + result['message'], outDuration: 600});
                return;
            }
            M.toast({html: 'memory of guest modified'});
            var memoryDisplayed = newMemory + ' MiB'
            $('#text_memory').text(memoryDisplayed);
            $('#current_memory').text(memoryDisplayed);
            N.WriteOperateLog('change memory of ' + instanceID + ' to ' + memoryDisplayed);
        },
        error: function (jqXHR, status, error) {
          M.toast({html: 'request modify memory fail: ' + error, outDuration: 600});
        }
      });
    }

    function showExtendDisk(index){
      var currentSize = ins['disks'][index];
      $('#current_disk').text( Math.floor(currentSize * 100 / GiB) / 100 + ' GiB');
      $('#extend_confirm').attr('onclick', 'extendDisk('+ index +')');
      var instance = M.Modal.getInstance($('#modal_disk'));
      instance.open();
    }

    function extendDisk(index){
      var currentSize = ins['disks'][index];
      var newDisk = Number($('#new_disk').val());
      $('#new_disk').val('');
      if (!Number.isInteger(newDisk)){
        M.toast({html: 'invalid disk size'});
        return
      }
      var diskInBytes = newDisk * GiB;
      if (diskInBytes <= currentSize){
        M.toast({html: 'must larger than current disk'});
        return
      }
      var request = new Object();
      request.size = diskInBytes;
      $.ajax({
        url: '/guests/' + instanceID + '/disks/resize/' + index,
        method: "PUT",
        dataType: "json",
        data: JSON.stringify(request),
        success: function (result) {
            if (0 != result['error_code']) {
                M.toast({html: 'modify disk size fail: ' + result['message'], outDuration: 600});
                return;
            }
            M.toast({html: 'disk size modified'});
            var diskDisplayed = newDisk + ' GiB';
            ins['disks'][index] = diskInBytes;
            $('#text_disk_' + index).text(diskDisplayed);
            N.WriteOperateLog('extend disk of ' + instanceID + ' to ' + diskDisplayed);
        },
        error: function (jqXHR, status, error) {
          M.toast({html: 'request modify disk size fail: ' + error, outDuration: 600});
        }
      });
    }

    function showShrinkDisk(index){
      var currentSize = ins['disks'][index];
      $('#shrink_confirm').attr('onclick', 'shrinkDisk('+ index +')');
      var instance = M.Modal.getInstance($('#modal_shrink'));
      instance.open();
    }

    function shrinkDisk(index){
      var request = new Object();
      N.WriteOperateLog('try shrink disk of ' + instanceID);
      $.ajax({
        url: '/guests/' + instanceID + '/disks/shrink/' + index,
        method: "PUT",
        dataType: "json",
        data: JSON.stringify(request),
        success: function (result) {
            if (0 != result['error_code']) {
                M.toast({html: 'shrink volume fail: ' + result['message'], outDuration: 600});
                return;
            }
            M.toast({html: 'volume sharnk finished'});
        },
        error: function (jqXHR, status, error) {
          M.toast({html: 'request shrink volume fail: ' + error, outDuration: 600});
        }
      });
    }

    function showPassword(){
      var url = '/guests/' + instanceID + '/auth';
      $.getJSON(
        url,
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'fetch password fail: ' + result['message'], outDuration: 600});
              return;
          }
          var auth = result['data'];
          var user = "", password = "";
          if (auth.hasOwnProperty('user')){
            user = auth['user'];
          }
          if (auth.hasOwnProperty('password')){
            password = auth['password'];
          }
          $('#text_password').text(user + ' : ' + password);
        }
      );
    }
    function showMonitorPassword(){
      var url = '/guests/' + instanceID;
      $.getJSON(
        url,
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'fetch password fail: ' + result['message'], outDuration: 600});
              return;
          }
          var auth = result['data'];
          var password = "";
          if (auth.hasOwnProperty('monitor_secret')){
            password = auth['monitor_secret'];
          }
          $('#text_monitor_secret').text( password);
        }
      );
    }

    function showModifyPassword(){
      var url = '/guests/' + instanceID + '/auth';
      $.getJSON(
        url,
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'fetch password fail: ' + result['message'], outDuration: 600});
              return;
          }
          var auth = result['data'];
          if (auth.hasOwnProperty('user')){
            var user = auth['user'];
            $('#new_user').val(user);
            M.updateTextFields();
          }
          var instance = M.Modal.getInstance($('#modal_password'));
          instance.open();
        }
      );
    }

    function changePassword(){
      var user = $('#new_user').val();
      if ('' == user){
        M.toast({html: 'must specify admin name'});
        return;
      }
      var password = "";
      if ('' != $('#new_password').val()){
        password = $('#new_password').val();
      }

      var request = new Object();
      request.user = user;
      request.password = password;
      $.ajax({
        url: '/guests/' + instanceID + '/auth',
        method: "PUT",
        dataType: "json",
        data: JSON.stringify(request),
        success: function (result) {
            if (0 != result['error_code']) {
                M.toast({html: 'change password fail: ' + result['message'], outDuration: 600});
                return;
            }
            M.toast({html: 'password modified'});
            N.WriteOperateLog('modify guest password of ' + instanceID);
        },
        error: function (jqXHR, status, error) {
          M.toast({html: 'request change password fail: ' + error, outDuration: 600});
        }
      });
    }

    function showModifyPriority(priority){
      var title, current, label;
      if (N.IsChinese()){
        title = '修改CPU优先级';
      }else{
        title = 'Modify Priority';
      }
      var priorityData;
      if(N.IsChinese()){
        priorityData = [
          ["high", "高", false],
          ["medium", "中", true],
          ["low", "低", false]
        ];
      }else{
        priorityData = [
          ["high", "High", false],
          ["medium", "Medium", true],
          ["low", "Low", false]
        ];
      }
      var inputContainer = $('<div>').addClass('input-field');
      priorityData.forEach((data)=>{
        var value = data[0];
        var label = data[1];
        var isChecked = data[2];
        var input = $('<input>').addClass('with-gap').attr('name', 'priority').attr('type', 'radio').val(value);
        if(priority == value){
          input.prop('checked', true);
        }
        inputContainer.append(
          $('<div>').addClass('col m2').append(
            $('<label>').append(
              input
            ).append(
              $('<span>').text(label)
            )
          )
        );
      });

      $('#modal-content').empty().append(
        $('<h4>').text(title)
      ).append(
        $('<div>').addClass('row').append(inputContainer)
      );
      var modifyPriority = function(){
        var request = new Object();
        request.priority = $('input[name=priority]:checked').val();
        var requestURL = '/guests/' + instanceID + '/qos/cpu/';
        $.ajax({
          url: requestURL,
          method: "PUT",
          dataType: "json",
          data: JSON.stringify(request),
          success: function (result) {
              if (0 != result['error_code']) {
                  M.toast({html: 'modify priority fail: ' + result['message'], outDuration: 600});
                  return;
              }
              M.toast({html: 'priority modified'});
              setTimeout(refresh, 500);
              N.WriteOperateLog('modify CPU priority of ' + instanceID);
          },
          error: function (jqXHR, status, error) {
            M.toast({html: 'request modify priority fail: ' + error, outDuration: 600});
          }
        });
      }
      $('#modal-confirm-button').unbind('click').click(modifyPriority);
      M.Modal.getInstance($('#modal-container')).open();
    }

    function showModifyIOPS(currentIOPS){
      var title;
      if (N.IsChinese()){
        title = '修改磁盘读写限制';
      }else{
        title = 'Modify Disk Read/Write Limit';
      }
      var onIOPSChanged = function(){
        var currentValue = $('#iops').val();
        if(0 == currentValue){
          if(N.IsChinese()){
            $('#iops-tip').text('无限制');
          }else{
            $('#iops-tip').text("No limit");
          }
        }else {
          $('#iops-tip').text(currentValue + ' IOPS');
        }
      }
      const minSize = 0, maxSize = 2000, moveStep = 10;

      var inputContainer = $('<div>').addClass('input-field');
      inputContainer.append(
        $('<div>').addClass('row').append(
          $('<div>').addClass('col m4 range-field').append(
            $('<input>').attr('type', 'range').attr('id', 'iops')
              .attr('min', minSize).attr('max', maxSize)
              .attr('value', currentIOPS).attr('step', moveStep).click(onIOPSChanged)
          )
        ).append(
          $('<div>').addClass('col m2').append(
            $('<label>').append(
              $('<span>').attr('id', 'iops-tip')
            )
          )
        )
      );

      $('#modal-content').empty().append(
        $('<h4>').text(title)
      ).append(
        $('<div>').addClass('row').append(inputContainer)
      );
      var modifyDiskIO = function(){
        var request = new Object();
        var iops = Number($('#iops').val());
        request.write_iops = iops;
        request.read_iops = iops;
        var requestURL = '/guests/' + instanceID + '/qos/disk/';
        $.ajax({
          url: requestURL,
          method: "PUT",
          dataType: "json",
          data: JSON.stringify(request),
          success: function (result) {
              if (0 != result['error_code']) {
                  M.toast({html: 'modify IOPS fail: ' + result['message'], outDuration: 600});
                  return;
              }
              M.toast({html: 'disk IOPS modified'});
              setTimeout(refresh, 500);
              N.WriteOperateLog('modify disk IOPS of ' + instanceID);
          },
          error: function (jqXHR, status, error) {
            M.toast({html: 'request modify IOPS fail: ' + error, outDuration: 600});
          }
        });
      }
      $('#modal-confirm-button').unbind('click').click(modifyDiskIO);
      onIOPSChanged();
      M.Range.init($('input[type=range]'));
      M.Modal.getInstance($('#modal-container')).open();
    }

    function showModifyBandWidth(currentInbound, currentOutbound){
      var title, inboundLabel, outboundLabel;
      if (N.IsChinese()){
        title = '修改网络带宽限制';
        inboundLabel = "下行带宽";
        outboundLabel = "上行带宽";
      }else{
        title = 'Modify Network Bandwidth';
        inboundLabel = "Inbound Bandwidth";
        outboundLabel = "Outbound Bandwidth";
      }

      var onInboundChanged = function(){
        var currentValue = $('#inbound').val();
        if(0 == currentValue){
          if(N.IsChinese()){
            $('#inbound-tip').text('无限制');
          }else{
            $('#inbound-tip').text("Unlimited");
          }
        }else {
          $('#inbound-tip').text(currentValue + ' Mbit/s');
        }
      }

      var onOutboundChanged = function(){
        var currentValue = $('#outbound').val();
        if(0 == currentValue){
          if(N.IsChinese()){
            $('#outbound-tip').text('无限制');
          }else{
            $('#outbound-tip').text("Unlimited");
          }
        }else {
          $('#outbound-tip').text(currentValue + ' Mbit/s');
        }
      }

      const minSize = 0, maxSize = 20, moveStep = 1;
      const mbitOffset = 20 - 3;
      var inputContainer = $('<div>').addClass('input-field');
      inputContainer.append(
        $('<div>').addClass('row').append(
          //label
          $('<div>').addClass('col m2').append(
            $('<label>').text(inboundLabel)
          )
        ).append(
          $('<div>').addClass('col m3 range-field').append(
            $('<input>').attr('type', 'range').attr('id', 'inbound')
              .attr('min', minSize).attr('max', maxSize)
              .attr('value', currentInbound >> mbitOffset).attr('step', moveStep).click(onInboundChanged)
          )
        ).append(
          $('<div>').addClass('col m2').append(
            $('<label>').append(
              $('<span>').attr('id', 'inbound-tip')
            )
          )
        )
      ).append(
        $('<div>').addClass('row').append(
          //label
          $('<div>').addClass('col m2').append(
            $('<label>').text(outboundLabel)
          )
        ).append(
          $('<div>').addClass('col m3 range-field').append(
            $('<input>').attr('type', 'range').attr('id', 'outbound')
              .attr('min', minSize).attr('max', maxSize)
              .attr('value', currentOutbound >> mbitOffset).attr('step', moveStep).click(onOutboundChanged)
          )
        ).append(
          $('<div>').addClass('col m2').append(
            $('<label>').append(
              $('<span>').attr('id', 'outbound-tip')
            )
          )
        )
      );

      $('#modal-content').empty().append(
        $('<h4>').text(title)
      ).append(
        inputContainer
      );
      var modifyBandWidth = function(){
        var request = new Object();
        const mps = 1 << (20 - 3);
        request.receive_speed = $('#inbound').val()  * mps;
        request.send_speed = $('#outbound').val()  * mps;
        var requestURL = '/guests/' + instanceID + '/qos/network/';
        $.ajax({
          url: requestURL,
          method: "PUT",
          dataType: "json",
          data: JSON.stringify(request),
          success: function (result) {
              if (0 != result['error_code']) {
                  M.toast({html: 'modify bandwidth fail: ' + result['message'], outDuration: 600});
                  return;
              }
              M.toast({html: 'disk bandwidth modified'});
              setTimeout(refresh, 500);
              N.WriteOperateLog('modify bandwidth of ' + instanceID);
          },
          error: function (jqXHR, status, error) {
            M.toast({html: 'request modify bandwidth fail: ' + error, outDuration: 600});
          }
        });
      }
      $('#modal-confirm-button').unbind('click').click(modifyBandWidth);
      onInboundChanged();
      onOutboundChanged();
      M.Range.init($('input[type=range]'));
      M.Modal.getInstance($('#modal-container')).open();
    }

    $(function(){

      M.Modal.init($('.modal'));
      var params = parseQueryString();
      if (!params.has('pool')){
        M.toast({html: 'must specify pool name'})
        return;
      }
      if (!params.has('instance')){
        M.toast({html: 'must specify instance'})
        return;
      }
      poolName = params.get('pool');
      $('#breadcrumb-path').append(
        $('<a>').addClass('breadcrumb').text(poolName).attr('href','instance_list.html?pool=' + poolName)
      );
      if (params.has('cell')){
        cellName = params.get('cell');
        $('#breadcrumb-path').append(
          $('<a>').addClass('breadcrumb').text(cellName).attr('href', 'instance_list.html?pool=' + poolName + '&cell=' + cellName)
        );
      }

      instanceID = params.get('instance');
      $('#breadcrumb-path').append(
        $('<a>').addClass('breadcrumb').text(instanceID)
      );

      loadInstance();

    });

</script>
</body>
</html>
